package com.util;

/**
 * Created by wlc on 2018/1/12.
 */

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.SCPClient;
import ch.ethz.ssh2.Session;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;


public class FileUtil {
    private static final String REMOTE_FILE_SERVER_IP = "192.168.0.14";
    private static final Integer REMOTE_FILE_SERVER_PORT = 22;

    /**
     * 创建不存在的文件
     *
     * @param destFileName
     * @return
     */
    public static boolean createFile(String destFileName) {
        File file = new File(destFileName);
        if (file.exists()) {
            System.out.println("创建单个文件" + destFileName + "失败，目标文件已存在！");
            return false;
        }
        if (destFileName.endsWith(File.separator)) {
            System.out.println("创建单个文件" + destFileName + "失败，目标文件不能为目录！");
            return false;
        }
        //判断目标文件所在的目录是否存在
        if (!file.getParentFile().exists()) {
            //如果目标文件所在的目录不存在，则创建父目录
            System.out.println("目标文件所在目录不存在，准备创建它！");
            if (!file.getParentFile().mkdirs()) {
                System.out.println("创建目标文件所在目录失败！");
                return false;
            }
        }
        //创建目标文件
        try {
            if (file.createNewFile()) {
                System.out.println("创建单个文件" + destFileName + "成功！");
                return true;
            } else {
                System.out.println("创建单个文件" + destFileName + "失败！");
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("创建单个文件" + destFileName + "失败！" + e.getMessage());
            return false;
        }
    }

    public static String createTempFile(String prefix, String suffix, String dirName) {
        File tempFile = null;
        if (dirName == null) {
            try {
                //在默认文件夹下创建临时文件
                tempFile = File.createTempFile(prefix, suffix);
                //返回临时文件的路径
                return tempFile.getCanonicalPath();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("创建临时文件失败！" + e.getMessage());
                return null;
            }
        } else {
            File dir = new File(dirName);
            //如果临时文件所在目录不存在，首先创建
            if (!dir.exists()) {
                if (!FileUtil.createDir(dirName)) {
                    System.out.println("创建临时文件失败，不能创建临时文件所在的目录！");
                    return null;
                }
            }
            try {
                //在指定目录下创建临时文件
                tempFile = File.createTempFile(prefix, suffix, dir);
                return tempFile.getCanonicalPath();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("创建临时文件失败！" + e.getMessage());
                return null;
            }
        }
    }

    private static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            System.out.println("创建目录" + destDirName + "失败，目标目录已经存在");
            return false;
        }
        if (!destDirName.endsWith(File.separator)) {
            destDirName = destDirName + File.separator;
        }
        //创建目录
        if (dir.mkdirs()) {
            System.out.println("创建目录" + destDirName + "成功！");
            return true;
        } else {
            System.out.println("创建目录" + destDirName + "失败！");
            return false;
        }
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir 将要删除的文件目录
     * @return boolean Returns "true" if all deletions were successful.
     * If a deletion fails, the method stops attempting to
     * delete and returns "false".
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            //         递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    /**
     * 从指定目录读取文件内容
     *
     * @param destFileName
     * @return
     * @throws IOException
     */
    public static ArrayList<String> readFile(String destFileName) throws IOException {
        InputStreamReader in = new InputStreamReader(new FileInputStream(destFileName), "UTF-8");
        BufferedReader br = new BufferedReader(in);
        ArrayList<String> content = new ArrayList<>();
        String temp;
        while ((temp = br.readLine()) != null) {  //按行读取文件内容
            content.add(temp);
        }
        br.close();
        return content;
    }

    /**
     * 向指定文件中写入内容（覆盖写）
     *
     * @param destFileName
     * @param content
     * @throws IOException
     */
    public static void writeFile(String destFileName, ArrayList<String> content) throws IOException {
        OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(destFileName), "UTF-8");
        BufferedWriter bw = new BufferedWriter(out);
        for (String row_content : content) {
            bw.write(row_content);
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }

    /**
     * 递归读取指定目录下所有文件对象
     * @param destFileDir
     * @return
     */
    public static ArrayList<File> readFilesObject(String destFileDir) {
        ArrayList<File> fileList = new ArrayList<File>();
        File file = new File(destFileDir);
        File[] files = file.listFiles();// 获取目录下的所有文件或文件夹
        if (files == null) {// 如果目录为空，直接退出
            return fileList;
        }
        // 遍历，目录下的所有文件
        for (File f : files) {
            if (f.isFile()) {
                fileList.add(f);
            } else if (f.isDirectory()) {
                fileList.addAll(readFilesObject(f.getAbsolutePath()));
            }
        }
        return fileList;
    }


    /**
     * 读取当前用户id路径下文件目录下.txt文件对象
     * @param destFileDir
     * @return
     */
    public static ArrayList<File> readFileCatalog(String destFileDir) {
        ArrayList<File> filelist = new ArrayList<>();
        File dirFile = new File(destFileDir);
        File[] files = dirFile.listFiles();              //读取目录下以文件夹为单位的消息

        if (files == null) {
            return filelist;
        }
        for (File f : files) {
            if (f.isDirectory()) {
                File[] fileArr = f.listFiles();
                if (fileArr != null) {
                    for (File floor : fileArr) {
                        String fileName = floor.getName();
                        String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
                        if (prefix.equals("txt")) {
                            filelist.add(floor);
                        }
                    }// for 判断后缀是否为.txt
                }
            } //  if 判断是否是目录
        }  // foreach 遍历一层文件目录
        return filelist;
    }

    /**
     * 获取消息目录下图片文件
     * @param destPath
     * @return
     */
    public static ArrayList<File> readImageFile(String destPath) {
        ArrayList<File> images = new ArrayList<>();
        File dirFile = new File(destPath);
        if (!dirFile.isDirectory()) {
            return images;
        }
        File[] files = dirFile.listFiles();
        if (files != null) {
            for (File file : files) {
                if (ImageUtil.isImage(file)) {
                    images.add(file);
                }
            }
        }
        return images;
    }

    /**
     * 骨肿瘤随访数据上传
     * @param path
     * @param fileName
     * @param response
     */
    public static void file_download(String path, String fileName, HttpServletResponse response) {
        response.reset();
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName.substring(fileName.lastIndexOf("\\") + 1));

        String abs_path = path + fileName;
        System.out.println("download_file_path: " + abs_path);
        File file = new File(abs_path);
        try {
            FileInputStream in = new FileInputStream(file);
            ServletOutputStream out = response.getOutputStream();
            int b = 0;
            byte[] buffer = new byte[1024];
            while (b != -1) {
                b = in.read(buffer);
                out.write(buffer, 0, b);
            }
            in.close();
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传存储
     * @param path
     * @param file_name
     * @param file
     */
    public static void data_upload(String path, String file_name, MultipartFile file) {
        if (file_name != null && FileUtil.createFile(path + file_name)) {
            File des_file = new File(path + file_name);
            try {
                file.transferTo(des_file);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void file_remote_download(String path, String fileName, HttpServletResponse response) throws IOException {
        String ip = REMOTE_FILE_SERVER_IP;
        int port = REMOTE_FILE_SERVER_PORT;
        response.reset();
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + path.substring(path.lastIndexOf('/') + 1, path.length()));

        Connection conn = null;
        SCPClient client = null;
        Session session = null;

        // 连接
        try {
            conn = new Connection(ip, port);
            conn.connect();
            conn.authenticateWithPassword("tjx", "waas87157078");
            session = conn.openSession();
            client = conn.createSCPClient();

        } catch (Exception e) {
            e.printStackTrace();
        }
        //
        InputStream in = null;
        if (session != null && client != null && conn != null) {
            try {
                client.get(path, response.getOutputStream());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 远程服务器文件是否存在
     *
     * @param path
     */
    public static boolean remote_file_exist(String path) {

        Connection conn = null;
        Session session = null;

        String file_name = path.substring(path.lastIndexOf('/') + 1, path.length());
        String file_dir = path.substring(0, path.lastIndexOf('/'));

        int len = -1;
        byte[] buffer = new byte[1024];
        // 连接
        try {
            conn = new Connection(REMOTE_FILE_SERVER_IP, REMOTE_FILE_SERVER_PORT);
            conn.connect();
            conn.authenticateWithPassword("tjx", "waas87157078");
            session = conn.openSession();
            InputStream stdout = session.getStdout();
            session.execCommand("ls " + file_dir + " | grep " + file_name);
            len = stdout.read(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return len > 0;
    }

    /**
     * 本地服务器文件是否存在
     *
     * @param train_file_path
     */
    public static boolean local_file_exist(String train_file_path) {
        File file = new File(train_file_path);
        return file.exists();
    }

}